home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Freeware 1998 June
/
SGI Freeware 1998 June.iso
/
dist
/
fw_ATxgopher.idb
/
usr
/
freeware
/
src
/
xgopher.1.3
/
cso.c.z
/
cso.c
Wrap
C/C++ Source or Header
|
1998-01-21
|
20KB
|
903 lines
/* cso.c
processing for CSO name server support */
/*---------------------------------------------------------------*/
/* Xgopher version 1.3 08 April 1993 */
/* version 1.2 20 November 1992 */
/* version 1.1 20 April 1992 */
/* version 1.0 04 March 1992 */
/* X window system client for the University of Minnesota */
/* Internet Gopher System. */
/* Allan Tuchman, University of Illinois at Urbana-Champaign */
/* Computing and Communications Services Office */
/* Copyright 1992, 1993 by */
/* the Board of Trustees of the University of Illinois */
/* Permission is granted to freely copy and redistribute this */
/* software with the copyright notice intact. */
/*---------------------------------------------------------------*/
/* Some of the "look and feel" of this panel has been influenced
by xph, an X window system interface for ph. xph was developed by
Bradley C. Spatz, University of Florida, bcs@ufl.edu.
xph goes beyond the capabilities presented here by providing the
editing functions for changing attributes. As gopher is an
information server, it is prudent to keep the name server
interface as simple as possible. */
#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/SmeBSB.h>
#include "osdep.h"
#include "cso.h"
#include "help.h"
#include "gui.h"
#include "appres.h"
#include "compatR4.h"
#include "xglobals.h"
#define CSO_SHELL_TITLE "CSO Name Server"
static void textAppend();
static Widget topLevel;
static Widget csoShell,
doQueryButton, queryText, csoText,
nameServerLabel;
static Boolean csoPanelCreated = False;
static Boolean panelActive = False;
static int nsFile = -1;
static int endOfText = 0;
#define THIS_POPUP_NAME "csoPopup"
/* default values */
static popupPosResources placement = {
/* position at the top of the main panel, 2/3 of the way across */
from_main, 66, 0, justify_top_left, justify_top_left, True, True
};
/* ph interface routines */
#define DELIM ':'
#define PH_TOKEN_LEN 256
#define DASHES " -------------------------------------------------\n"
#define PH_BUFFSIZE 256
static char phCommand[PH_BUFFSIZE];
static char phResponse[PH_BUFFSIZE];
/* these macros are used for every read from the ph name server. The
result buffer is global, so it is hard coded. */
#define RD_RESP(s) \
{int n; \
if ((n = readDelim(s, phResponse, PH_BUFFSIZE-1, DELIM)) <= 0)\
{ ph_readError(n); return False; } }
#define RD_LINE(s) \
{int n; \
if ((n = readLine(s, phResponse, PH_BUFFSIZE-1)) <= 0)\
{ ph_readError(n); return False; } }
static char mailDomain[PH_TOKEN_LEN];
/* ph_readError
error reading response from ph */
static void
ph_readError(n)
int n;
{
if (n == 0)
showError("End of file from Name Server!");
else
showError("Read error from Name Server!");
return;
}
/* ph_id
send id command to ph */
static Boolean
ph_id(s)
int s;
{
int n, rc;
sprintf(phCommand, "id %d\n", getuid());
write(s, phCommand, strlen(phCommand));
do {
RD_RESP(s);
rc = atoi(phResponse);
RD_LINE(s);
} while (rc < 200);
return True;
}
/* ph_quit
send quit command to ph */
static Boolean
ph_quit(s)
int s;
{
int n, rc;
sprintf(phCommand, "quit\n");
write(s, phCommand, strlen(phCommand));
do {
RD_RESP(s);
rc = atoi(phResponse);
RD_LINE(s);
} while (rc < 200);
return True;
}
/* ph_siteinfo
send siteinfo command to ph */
static Boolean
ph_siteinfo(s, mail)
int s;
char *mail;
{
int n, rc;
*mail= '\0';
sprintf(phCommand, "siteinfo\n");
write(s, phCommand, strlen(phCommand));
do {
RD_RESP(s);
if ((rc = atoi(phResponse)) >= 200) {
RD_LINE(s);
break;
}
/* read entry index */
RD_RESP(s);
/* read field name */
RD_RESP(s);
if (strcmp(phResponse, "maildomain") == 0) {
RD_RESP(s);
strncpy(mail, phResponse, PH_TOKEN_LEN);
} else {
RD_LINE(s);
}
} while (rc < 200);
return True;
}
/* ph_query
send query command to ph */
static Boolean
ph_query(s, string)
int s;
char *string;
{
int rc, n, entry, lastEntry=1;
Boolean lastLine;
sprintf (phCommand, "ph %s\n", string);
write(s, phCommand, strlen(phCommand));
lastLine = False;
do {
RD_RESP(s);
if ((rc = atoi(phResponse)) >= 200) {
lastLine = True;
RD_LINE(s);
textAppend (phResponse);
break;
}
rc = abs(rc);
if (rc/100 != 2) {
RD_LINE(s);
textAppend (phResponse);
continue;
}
/* read entry index */
RD_RESP(s);
entry = atoi(phResponse);
if (entry != lastEntry) {
textAppend (DASHES);
lastEntry = entry;
}
/* report remainder of line */
RD_LINE(s);
textAppend (phResponse);
} while (! lastLine);
return True;
}
/* matchToken
see if a token is contained in a string of tokens. Tokens are
delimited by white space (spaces, tabs, newline). */
static Boolean
matchToken(s, token)
char *s, *token;
{
char *p = s;
int tokenLen = strlen(token);
char *last = s + (strlen(s) - tokenLen);
while (p < last) {
while ((*p == ' ' || *p == '\t' || *p == '\n') &&
p < last) p++;
if (strncmp(p, token, tokenLen) == 0) {
p += tokenLen;
if (*p == ' ' || *p == '\t' || *p == '\n')
return True;
}
while ((*p != ' ' && *p != '\t' && *p != '\n') &&
p < last) p++;
}
return False;
}
/* ph_fields
send fields command to ph */
static Boolean
ph_fields(s, string)
int s;
char *string;
{
int rc, n, entry, lastEntry = -1;
Boolean lastLine, descriptionLine, use;
char fieldName[PH_TOKEN_LEN];
sprintf (phCommand, "fields\n");
write(s, phCommand, strlen(phCommand));
sprintf (phResponse, " ----- %s fields -----\n", string);
textAppend (phResponse);
lastLine = False;
do {
RD_RESP(s);
if ((rc = atoi(phResponse)) >= 200) {
lastLine = True;
RD_LINE(s);
textAppend (phResponse);
break;
}
rc = abs(rc);
if (rc/100 != 2) {
RD_LINE(s);
textAppend (phResponse);
continue;
}
/* read entry index */
RD_RESP(s);
entry = atoi(phResponse);
if (entry != lastEntry) {
lastEntry = entry;
descriptionLine = False;
use = False;
} else
descriptionLine = True;
/* read field name */
RD_RESP(s);
strcpy(fieldName, phResponse);
if (descriptionLine) {
RD_LINE(s);
if (use) {
sprintf (phCommand, "%s:\t %s",
fieldName, phResponse);
textAppend (phCommand);
} else ;
} else {
/* scan remainder of line for desired value */
RD_LINE(s);
/* loop through tokens */
if (matchToken(phResponse, string)) use = True;
}
} while (! lastLine);
return True;
}
/* X interface routines */
/* shutdownNameServer
remove the panel from the display and reset the file indicators */
shutdownNameServer()
{
Cardinal n;
Arg args[3];
XtPopdown(csoShell);
#ifndef TEST_CSO
close(nsFile);
#endif /* TEST_CSO */
nsFile = -1;
panelActive = False;
n=0;
XtSetArg(args[n], XtNlabel, ""); n++;
XtSetValues(nameServerLabel, args, n);
}
/* doneProc
finish a cso name server session */
static void
doneProc(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
#ifndef TEST_CSO
ph_quit(nsFile);
#endif /* TEST_CSO */
shutdownNameServer();
}
/* fieldsProc
list fields with some specification */
static void
fieldsProc(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
Cardinal n;
Arg args[3];
char *fieldName = (char *) clientData;
/* Lookup, Indexed, Public, Default */
if (! ph_fields(nsFile, fieldName) ) shutdownNameServer();
}
/* helpProc
provide help for a cso name server session */
static void
helpProc(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
showHelp("cso help");
}
/* doQueryProc
submit a query to a cso name server */
static void
doQueryProc(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
Cardinal n;
Arg args[3];
char *string;
n=0;
XtSetArg(args[n], XtNstring, &string); n++;
XtGetValues(queryText, args, n);
if (strlen(string) == 0) {
showError("First enter a name, then do the query.");
} else {
if (! ph_query(nsFile, string) ) shutdownNameServer();
}
}
/* QueryOk
accept the "do query" action from a keyboard <cr> instead of the
"do query" button. The <cr> translation is defined elsewhere.
Capitalized name is for X action proc convention. */
static void
QueryOk(w, event, parms, nparms)
Widget w;
XEvent *event;
String *parms;
Cardinal *nparms;
{
XtCallActionProc(doQueryButton, "set", NULL, NULL, 0);
WaitForAllPendingEventsAndExpose(
XtDisplay(csoShell),
(Window) NULL);
doQueryProc(w, NULL, NULL);
XtCallActionProc(doQueryButton, "unset", NULL, NULL, 0);
return;
}
/* CsoDone
accept the "csodone" action from an action instead of the
"done" button. The action translation is defined elsewhere.
Capitalized name is for X action proc convention. */
static void
CsoDone(w, event, parms, nparms)
Widget w;
XEvent *event;
String *parms;
Cardinal *nparms;
{
if (panelActive)
doneProc(w, NULL, NULL);
return;
}
/* removeCsoPanel
allow external force to issue the "done" instruction to the CSO panel */
void
removeCsoPanel()
{
if (panelActive)
doneProc(NULL, NULL, NULL);
return;
}
/* clearQueryProc
clear the name query text */
static void
clearQueryProc(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
Cardinal n;
Arg args[3];
n=0;
XtSetArg(args[n], XtNstring, ""); n++;
XtSetValues(queryText, args, n);
}
/* clearTextProc
clear the text result window */
static void
clearTextProc(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
Cardinal n;
Arg args[3];
n=0;
XtSetArg(args[n], XtNeditType, XawtextEdit); n++;
XtSetValues(csoText, args, n);
n=0;
XtSetArg(args[n], XtNstring, ""); n++;
XtSetValues(csoText, args, n);
n=0;
XtSetArg(args[n], XtNeditType, XawtextRead); n++;
XtSetValues(csoText, args, n);
endOfText = 0;
}
/* textAppend
append a string to the text result window */
static void
textAppend(string)
char *string;
{
Cardinal n;
Arg args[3];
XawTextBlock textBlock;
int length;
textBlock.firstPos = 0;
textBlock.length = strlen(string);
textBlock.ptr = string;
textBlock.format = FMT8BIT;
n=0;
XtSetArg(args[n], XtNeditType, XawtextAppend); n++;
XtSetValues(csoText, args, n);
XawTextReplace(csoText, endOfText, endOfText, &textBlock); n++;
endOfText += textBlock.length;
n=0;
XtSetArg(args[n], XtNeditType, XawtextRead); n++;
XtSetValues(csoText, args, n);
}
/* displayCsoPanel
display the panel for cso name server queries */
Boolean
displayCsoPanel(title, s)
char *title;
int s;
{
Arg args[10];
Cardinal n;
Dimension wt, wc;
Position relX, xc, yc;
static char geom[16];
n=0;
XtSetArg(args[n], XtNlabel, title); n++;
XtSetValues(nameServerLabel, args, n);
if (panelActive) {
clearQueryProc(NULL, NULL, NULL);
close(nsFile);
} else {
panelActive = True;
positionAPopup(csoShell, topLevel, &placement);
XtPopup (csoShell, XtGrabNone);
}
nsFile = s;
#ifndef TEST_CSO
if (! ph_id(nsFile) ) {
shutdownNameServer();
return False;
}
if (! ph_siteinfo(nsFile, mailDomain) ) {
shutdownNameServer();
return False;
}
#endif /* TEST_CSO */
if (appResources->warpCursor) {
Position X, Y;
findPopupPosition(csoShell, topLevel, &placement, &X, &Y);
XWarpPointer(XtDisplay(csoShell), None,
RootWindowOfScreen(XtScreen(csoShell)),
0, 0, 0, 0,
X+25, Y+100);
}
return True;
}
#define N_FIELDS 4
static char *fieldsLabel[] = {"Default", "Lookup", "Indexed", "Public"};
/* makeCsoPanel
create the X panel for CSO name server queries */
void
makeCsoPanel(top)
Widget top;
{
Arg args[10];
Cardinal n;
int i;
Widget csoForm;
Widget doneButton, helpButton,
clearQueryButton, clearTextButton,
fieldsMenuHolder, fieldsButton,
fieldsMenuItem[N_FIELDS],
queryLabel;
Dimension nameWidth, resultWidth;
static XtActionsRec csoActionsTable[] = {
{ "queryok", (XtActionProc) QueryOk },
{ "csodone", (XtActionProc) CsoDone }
};
if (csoPanelCreated) return;
topLevel = top;
/* create CSO NAME SERVER shell */
n=0;
XtSetArg(args[n], XtNtitle, CSO_SHELL_TITLE); n++;
csoShell = XtCreatePopupShell("csoShell",
topLevelShellWidgetClass,
topLevel, args, n);
/* create CSO NAME SERVER main panel form */
n=0;
csoForm = XtCreateManagedWidget("csoForm",
formWidgetClass,
csoShell, args, n);
/* create NAME SERVER label */
n=0;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainTop); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainRight); n++;
nameServerLabel = XtCreateManagedWidget("nameServer",
labelWidgetClass,
csoForm, args, n);
/* create DONE button */
n=0;
XtSetArg(args[n], XtNfromVert, nameServerLabel); n++;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainTop); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainLeft); n++;
doneButton = XtCreateManagedWidget("csoDone", commandWidgetClass,
csoForm, args, n);
XtAddCallback(doneButton, XtNcallback, doneProc, NULL);
XtAddCallback(doneButton, XtNcallback, clearQueryProc, NULL);
XtAddCallback(doneButton, XtNcallback, clearTextProc, NULL);
/* create FIELDS MENU holder */
n=0;
fieldsMenuHolder = XtCreateManagedWidget("csoFieldsMenu",
simpleMenuWidgetClass,
csoForm, args, n);
/* create FIELDS MENU ENTRIES */
for (i=0; i<N_FIELDS; i++) {
n=0;
XtSetArg(args[n], XtNlabel, fieldsLabel[i]); n++;
fieldsMenuItem[i] = XtCreateManagedWidget(fieldsLabel[i],
smeBSBObjectClass,
fieldsMenuHolder, args, n);
XtAddCallback(fieldsMenuItem[i], XtNcallback,
fieldsProc, fieldsLabel[i]);
}
/* create FIELDS button */
n=0;
XtSetArg(args[n], XtNmenuName, "csoFieldsMenu"); n++;
#ifndef XGOPHER_X11R4
XtSetArg(args[n], XtNleftBitmap, pulldownPixmap); n++;
#endif /* XGOPHER_X11R4 */
XtSetArg(args[n], XtNfromVert, nameServerLabel); n++;
XtSetArg(args[n], XtNfromHoriz, doneButton); n++;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainTop); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainLeft); n++;
fieldsButton = XtCreateManagedWidget("csoFields",
menuButtonWidgetClass,
csoForm, args, n);
/* create HELP button */
n=0;
XtSetArg(args[n], XtNfromVert, nameServerLabel); n++;
XtSetArg(args[n], XtNfromHoriz, fieldsButton); n++;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainTop); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainLeft); n++;
helpButton = XtCreateManagedWidget("csoHelp", commandWidgetClass,
csoForm, args, n);
XtAddCallback(helpButton, XtNcallback, helpProc, NULL);
/* create NAME label */
n=0;
XtSetArg(args[n], XtNfromVert, doneButton); n++;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainTop); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainRight); n++;
queryLabel = XtCreateManagedWidget("csoQueryLabel",
labelWidgetClass,
csoForm, args, n);
/* create NAME TEXT entry */
n=0;
XtSetArg(args[n], XtNeditType, XawtextEdit); n++;
XtSetArg(args[n], XtNstring, ""); n++;
XtSetArg(args[n], XtNfromVert, queryLabel); n++;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainTop); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainRight); n++;
queryText = XtCreateManagedWidget("csoQueryText",
asciiTextWidgetClass,
csoForm, args, n);
setTextWidgetSize(queryText, 60, 1);
n=0;
XtSetArg(args[n], XtNwidth, &nameWidth); n++;
XtGetValues(queryText, args, n);
XtOverrideTranslations(queryText, oneLineParsed);
/* create DO QUERY button */
n=0;
XtSetArg(args[n], XtNfromVert, queryText); n++;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainTop); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainLeft); n++;
doQueryButton = XtCreateManagedWidget("csoDoQuery", commandWidgetClass,
csoForm, args, n);
XtAddCallback(doQueryButton, XtNcallback,
doQueryProc, NULL);
/* create CLEAR QUERY button */
n=0;
XtSetArg(args[n], XtNfromVert, queryText); n++;
XtSetArg(args[n], XtNfromHoriz, doQueryButton); n++;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainTop); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainLeft); n++;
clearQueryButton = XtCreateManagedWidget("csoClearQuery",
commandWidgetClass,
csoForm, args, n);
XtAddCallback(clearQueryButton, XtNcallback,
clearQueryProc, NULL);
/* create CLEAR TEXT button */
n=0;
XtSetArg(args[n], XtNfromVert, queryText); n++;
XtSetArg(args[n], XtNfromHoriz, clearQueryButton); n++;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainTop); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainLeft); n++;
clearTextButton = XtCreateManagedWidget("csoClearText",
commandWidgetClass,
csoForm, args, n);
XtAddCallback(clearTextButton, XtNcallback,
clearTextProc, NULL);
/* create TEXT display */
n=0;
XtSetArg(args[n], XtNeditType, XawtextRead); n++;
XtSetArg(args[n], XtNstring, ""); n++;
XtSetArg(args[n], XtNfromVert, doQueryButton); n++;
XtSetArg(args[n], XtNtop, XawChainTop); n++;
XtSetArg(args[n], XtNbottom, XawChainBottom); n++;
XtSetArg(args[n], XtNleft, XawChainLeft); n++;
XtSetArg(args[n], XtNright, XawChainRight); n++;
csoText = XtCreateManagedWidget("csoText", asciiTextWidgetClass,
csoForm, args, n);
setTextWidgetSize(csoText, 60, 20);
n=0;
XtSetArg(args[n], XtNwidth, &resultWidth); n++;
XtGetValues(csoText, args, n);
if (nameWidth < resultWidth) {
n=0;
XtSetArg(args[n], XtNwidth, resultWidth); n++;
XtSetValues(queryText, args, n);
} else {
n=0;
XtSetArg(args[n], XtNwidth, nameWidth); n++;
XtSetValues(csoText, args, n);
}
XtAppAddActions(appcon, csoActionsTable, XtNumber(csoActionsTable));
XtSetKeyboardFocus(csoForm, queryText);
/* find the popup placement for this shell */
{
popupPosResources *resourcePlacement;
resourcePlacement = getPopupPosResources(
THIS_POPUP_NAME, POPUP_POS_CLASS, &placement);
bcopy( (char *) resourcePlacement, (char *) &placement,
sizeof(popupPosResources) );
}
setPopupGeometry(csoShell, &placement);
/* for ICCCM window manager protocol complience */
XtOverrideTranslations (csoShell,
XtParseTranslationTable ("<Message>WM_PROTOCOLS: csodone()"));
XtRealizeWidget(csoShell);
(void) XSetWMProtocols (XtDisplay(csoShell), XtWindow(csoShell),
&wmDeleteAtom, 1);
csoPanelCreated = True;
}